using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Win32;

namespace SAInterfaceLibrary
{
    /// <summary>
    /// Contains the config info that we need to access a particular
    /// configuration for builds (templates, dude).
    /// </summary>
    public abstract class ConfigMSVCVersionInfo
    {
        protected string _name;

        /// <summary>
        /// The name of this version. Suitable for user viewing.
        /// </summary>
        public string Name
        {
            get { return _name; }
        }

        /// <summary>
        /// Returns true if we know this version is on this machine and supported.
        /// </summary>
        public abstract bool IsOnMachine
        {
            get;
        }

        /// <summary>
        /// Return the location of the install directory
        /// </summary>
        public virtual string InstallDir
        {
            get
            {
                string result = GetRawInstallDir();
                if (result == null)
                {
                    throw new FileNotFoundException("Unable to find MSVC install directory");
                }
                return result;
            }
        }

        /// <summary>
        /// Gets back a raw string. Null if the dir is bad. This here is just
        /// to help out with some default behavior. Override either this or above if
        /// need be!
        /// </summary>
        /// <returns></returns>
        protected string GetRawInstallDir()
        {
            string dir = GetDirectory();
            if (dir == null)
            {
                return null;
            }
            if (!Directory.Exists(dir))
            {
                return null;
            }
            return dir;
        }

        /// <summary>
        /// Returns the directory that contains the installed directory!
        /// </summary>
        /// <returns></returns>
        protected virtual string GetDirectory()
        {
            string dir = null;
            RegistryKey k = Registry.LocalMachine.OpenSubKey(IDERegKey);
            if (k != null)
            {
                dir = (string)k.GetValue("InstallDir");
            }
            return dir;
        }

        /// <summary>
        /// The current registrly key
        /// </summary>
        protected virtual string IDERegKey
        {
            get { throw new Exception("IDERegKey is not implemented by the subclass!"); }
        }

        /// <summary>
        /// Place where the specific templates are held for this guy.
        /// </summary>
        protected string _template_dir;

        protected string _template_location = @"vc_project_template.vcproj";

        /// <summary>
        /// Gets the full directory for the VCPROJ template.
        /// </summary>
        public virtual string ProjectTempmlatePath
        {
            get
            {
                EventLogger.LogMessage("Getting project template path. Base template path is " + _template_dir, System.Diagnostics.EventLogEntryType.Information, 5);
                return _template_dir + "\\" + _template_location;
            }
        }

        /// <summary>
        /// Override if there are certian files that are not good, and should not be included in the converted files!
        /// </summary>
        /// <param name="finfo"></param>
        public virtual bool FileIsGood(FileInfo finfo)
        {
            return true;
        }

        /// <summary>
        /// Returns true if the config needs a settings file to work.
        /// </summary>
        public virtual bool UsesSettingsFile { get { return true; } }

        public class FileTransInfo
        {
            /// <summary>
            /// Where we can find the template
            /// </summary>
            public string TemplatePath;

            /// <summary>
            /// The name. Should include "root_build_project" which will be
            /// replaced by teh real project name. Or it will be totally ignored!
            /// </summary>
            public string FinalFileName;
        }

        private List<FileTransInfo> _files = new List<FileTransInfo>();

        public List<FileTransInfo> FilesToTranslate
        {
            get
            {
                /// THis would be simpler if we targeted LINQ!
                List<FileTransInfo> result = new List<FileTransInfo>();
                foreach (var f in _files)
                {
                    result.Add(new FileTransInfo()
                    {
                        FinalFileName = f.FinalFileName,
                        TemplatePath = _template_dir + "\\" + f.TemplatePath
                    });
                }

                return result;
            }
        }

        /// <summary>
        /// Add a new file fro translation.
        /// </summary>
        /// <param name="info"></param>
        protected void AddFileToTranslate (FileTransInfo info)
        {
            _files.Add(info);
        }

        /// <summary>
        /// Override the below guy to do special translation of some macros.
        /// </summary>
        /// <param name="input_string"></param>
        /// <returns></returns>
        public virtual string TranslateMacro(string input_string)
        {
            return null;
        }
    }
}
